package com.hyq.learn.security.warrper;

import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.io.IOUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

/**
 * @author : heyuqin
 * @since : 2024/03/06 14:57
 */
public class ContentCachingRequest extends HttpServletRequestWrapper {

    private static final String EMPTY_STRING = "";

    private byte[] payload;

    public ContentCachingRequest(HttpServletRequest request) throws IOException {
        super(request);
        InputStream inputStream = getRequest().getInputStream();
        this.payload = inputStream == null ? null : IOUtils.toByteArray(inputStream);
    }

    public String getPayloadString() {
        return payload == null ? EMPTY_STRING : new String(payload, StandardCharsets.UTF_8);
    }

    public byte[] getPayload() {
        return payload;
    }

    public void setPayload(byte[] payload) {
        this.payload = payload;
    }


    @Override
    public ServletInputStream getInputStream() throws IOException {
        if (payload == null) {
            return super.getInputStream();
        }
        return new CachingServletInputStream(payload);
    }

    private static final class CachingServletInputStream extends ServletInputStream {
        private final ByteArrayInputStream bis;

        private CachingServletInputStream(byte[] payload) {
            this.bis = new ByteArrayInputStream(payload);
        }

        @Override
        public boolean isFinished() {
            return false;
        }

        @Override
        public boolean isReady() {
            return false;
        }

        @Override
        public void setReadListener(ReadListener readListener) {

        }

        @Override
        public int read() throws IOException {
            return bis.read();
        }
    }
}
